package top.oauth2.server.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import top.oauth2.common.response.ResponseMessage;

import javax.sql.DataSource;
import java.util.List;

/**
 * SpringSecurity配置
 * @author xphu
 * @version 1.0
 * @date 2021/8/27 12:07
 */
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${secure.ignore.urls}")
    private String[] urls;
    /**
     * 登录账户密码校验的处理类
     */
    private final UserDetailsService userDetailsService;

    /**
     * redis
     */
    private final RedisTemplate redisTemplate;

    /**
     * 注入数据源
     */
    private final DataSource dataSource;

    public WebSecurityConfig(UserDetailsService userDetailsService, RedisTemplate redisTemplate, DataSource dataSource) {
        this.userDetailsService = userDetailsService;
        this.redisTemplate = redisTemplate;
        this.dataSource = dataSource;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 配置白名单：允许获取公钥接口的访问
        http
                // 表单登录
                .formLogin()
                .and()
                // 允许访问的
                .authorizeRequests().requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll()
//                .antMatchers("/rsa/publicKey", "/oauth/token", "/captcha/img").permitAll()
                .antMatchers(urls).permitAll()
                .anyRequest().authenticated()
                //禁用跨站伪造
                .and().csrf().disable();
    }

    /**
     *  创建 AuthenticationManager bean对象, 方便别的地方使用
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    /**
     * 密码编码器
     */
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

}
